From fa1dcff500816c53a31d595f2846b5dd9bc3a09d Mon Sep 17 00:00:00 2001 From: tsteven4 <13596209+tsteven4@users.noreply.github.com> Date: Wed, 27 Jan 2021 16:09:30 -0700 Subject: [PATCH] trust Qt to strip out characters illegal in xml. (#671) this was added in Qt 5.11.0. --- src/core/xmlstreamwriter.cc | 75 +++++++------------------------------ src/core/xmlstreamwriter.h | 29 ++------------ 2 files changed, 17 insertions(+), 87 deletions(-) diff --git a/src/core/xmlstreamwriter.cc b/src/core/xmlstreamwriter.cc index 5b66e4d26..6f6839ec1 100644 --- a/src/core/xmlstreamwriter.cc +++ b/src/core/xmlstreamwriter.cc @@ -19,75 +19,28 @@ #include "src/core/xmlstreamwriter.h" -#include -#include -#include -#include +#include // for QString +#include // for QXmlStreamWriter +#include // for QT_VERSION, QT_VERSION_CHECK // As this code began in C, we have several hundred places that write // c strings. Add a test that the string contains anything useful // before serializing an empty tag. -// We also strip out characters that are illegal in xml. These can creep -// into our structures from other formats where they are legal. +// We rely on Qt to strip out characters that are illegal in xml. These can +// creep into our structures from other formats where they are legal. -namespace gpsbabel -{ - -XmlTextCodec* XmlTextCodec::instance = new XmlTextCodec(); - -XmlTextCodec::XmlTextCodec() : QTextCodec() -{ - utf8Codec = QTextCodec::codecForName("UTF-8"); -} - -QByteArray XmlTextCodec::convertFromUnicode(const QChar* chars, int len, QTextCodec::ConverterState* state) const -{ -// Qt 4.7.4, 4.6.2 don't have IgnoreHeader set on the first call, which can -// result in a BOM being output by utf8Codec. - state->flags |= QTextCodec::IgnoreHeader; - QByteArray r = utf8Codec->fromUnicode(chars, len, state); - char* data = r.data(); - for (int i = 0; i < r.size(); i++) { - if ((0x00 <= data[i] && data[i] <= 0x08) || - (0x0b <= data[i] && data[i] <= 0x0c) || - (0x0e <= data[i] && data[i] <= 0x1f)) { - data[i] = ' '; - } - } - return r; -} +// Verify Qt is new enough to strip out illegal characters. +// This fix went into Qt 5.11.0. See +// https://github.com/GPSBabel/gpsbabel/issues/637 +// https://bugreports.qt.io/browse/QTBUG-63150 +// https://github.com/qt/qtbase/commit/3b5b8f1d4ab8092e5dd337b7b4e32d85fda2e0b7 +#if (QT_VERSION < QT_VERSION_CHECK(5, 11, 0)) +#error We rely on the fix for QTBUG-63150 introduced in Qt 5.11.0. +#endif -QString XmlTextCodec::convertToUnicode(const char* chars, int len, QTextCodec::ConverterState* state) const -{ - return utf8Codec->toUnicode(chars, len, state); -} -int XmlTextCodec::mibEnum() const -{ - return UTF8_FOR_XML_MIB; -} - -// Our name must not overlap with UTF-8 or it may be returned by QTextCodec::codecForName("UTF-8") -QByteArray XmlTextCodec::name() const -{ - return QByteArray("UTF-8-XML"); -} - -XmlStreamWriter::XmlStreamWriter(QString* string) : QXmlStreamWriter(string) -{ -} - -XmlStreamWriter::XmlStreamWriter(QFile* f) : QXmlStreamWriter(f) -{ - setCodec(XmlTextCodec::instance); -} - -// We must override the encoding, we don't want to use XmlTextCode::name(). -void XmlStreamWriter::writeStartDocument() +namespace gpsbabel { - writeProcessingInstruction(QStringLiteral("xml version=\"1.0\" encoding=\"UTF-8\"")); -} - // Dont emit the element if there's nothing interesting in it. void XmlStreamWriter::writeOptionalTextElement(const QString& qualifiedName, const QString& text) { diff --git a/src/core/xmlstreamwriter.h b/src/core/xmlstreamwriter.h index 5207634f4..a96ed982c 100644 --- a/src/core/xmlstreamwriter.h +++ b/src/core/xmlstreamwriter.h @@ -20,43 +20,20 @@ #ifndef XMLSTREAMWRITER_H #define XMLSTREAMWRITER_H -#include -#include - -class QFile; +#include // for QString +#include // for QXmlStreamWriter namespace gpsbabel { -// From the "vendor" range, see: -// https://www.iana.org/assignments/character-sets/character-sets.xhtml -const int UTF8_FOR_XML_MIB = 2000; - -class XmlTextCodec : public QTextCodec -{ -private: - QTextCodec* utf8Codec; -public: - XmlTextCodec(); - static XmlTextCodec *instance; - QByteArray name() const override; - int mibEnum() const override; -protected: - QByteArray convertFromUnicode(const QChar* chars, int len, QTextCodec::ConverterState* state) const override; - QString convertToUnicode(const char* chars, int len, QTextCodec::ConverterState* state) const override; -}; - class XmlStreamWriter : public QXmlStreamWriter { public: - explicit XmlStreamWriter(QString* string); - explicit XmlStreamWriter(QFile* f); + using QXmlStreamWriter::QXmlStreamWriter; - void writeStartDocument(); void writeOptionalTextElement(const QString& qualifiedName, const QString& text); }; } // namespace gpsbabel #endif // XMLSTREAMWRITER_H - -- 2.30.2